package com.yycx.module.bus.provider.service.impl;

import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.constants.CommonConstants;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaDelete;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.utils.ApiAssert;
import com.yycx.common.utils.DateUtils;
import com.yycx.module.bus.client.entity.*;
import com.yycx.module.bus.provider.mapper.BusFinanceDetailsMapper;
import com.yycx.module.bus.provider.service.*;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.module.system.client.entity.SysCompany;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.xml.ws.Action;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对账明细接口实现类
 *
 * @author flyme
 * @date 2021-01-10
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BusFinanceDetailsServiceImpl extends BaseServiceImpl<BusFinanceDetailsMapper, BusFinanceDetails> implements BusFinanceDetailsService {

    @Resource
    private BusOrderDetailsService orderDetailsService;

    @Resource
    private BusFinanceService busFinanceService;

    @Resource
    private BusDeptService deptService;

    @Resource
    private BusCustomService customService;

    @Resource
    private BusDrugsService drugsService;


    @Resource
    private BusDrugslotService drugslotService;

    @Resource
    private BusSalemanService salemanService;

    @Resource
    private BusOrderService orderService;


    @Override
    public ResultBody beforeAdd(CriteriaSave cs, BusFinanceDetails bfd, EntityMap extra) {
        String orderNo = cs.getParams("orderNo");
        Long financeId = cs.getLong("financeId");
        ApiAssert.isNotEmpty("修正原订单号不能为空", orderNo);
        BusOrder order = orderService.getByProperty("orderNo", orderNo);
        ApiAssert.isNotEmpty("修正原订单不存在", order);
        bfd.setOrderId(order.getOrderId());
        BusDept dept = deptService.getById(order.getDeptId());
        bfd.setDeptName(dept.getDeptName());
        bfd.setSaleDate(DateUtils.formatDate(order.getSendDate()));
        bfd.setFinanceId(financeId);
        return ResultBody.ok();
    }


    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ResultBody beforePageList(CriteriaQuery<BusFinanceDetails> cq, BusFinanceDetails bfd, EntityMap requestMap) {
        cq.orderByDesc("bfd.createTime");
        return ResultBody.ok();
    }

    /**
     * 统计上期数据
     *
     * @param benQiFinance
     * @return
     */
    @Override
    public List<BusFinanceDetails> selectLastByFinanceId(BusFinance benQiHjFinance) {
        //对账表月份第一天
        String firstDay = benQiHjFinance.getFinanceMonth() + "-01";
        List<BusFinanceDetails> detailsList = new ArrayList<>();
        if (FlymeUtils.isNotEmpty(benQiHjFinance)) {
            Long saleManId = benQiHjFinance.getSaleManId();
            Long deptId = benQiHjFinance.getDeptId();
            CriteriaQuery cq = new CriteriaQuery(BusOrderDetails.class);
            cq.lt("saleDate", firstDay);
            cq.eq(true, "saleManId", saleManId);
            cq.eq(true, "deptId", deptId);
            //非补单
            cq.ne(true, "budan", benQiHjFinance.getFinanceMonth());
            cq.eq(true, "orderDetailsState", CommonConstants.ENABLED);
            cq.orderByAsc("saleDate");
            List<BusOrderDetails> orderDetailsList = orderDetailsService.list(cq);
            //计算累计数据
            detailsList = initLastBusFinanceDetails(orderDetailsList, benQiHjFinance);
        }
        return detailsList;
    }

    @Override
    public void removeByFinanceId(Serializable financeId) {
        CriteriaDelete cd = new CriteriaDelete();
        cd.eq(true, "financeId", financeId);
        remove(cd);
    }

    /**
     * 初始化对账明细
     *
     * @param benQiHjFinance
     */
    @Override
    public List<BusFinanceDetails> initThisBusFinanceDetails(BusFinance benQiHjFinance) {
        if (FlymeUtils.isNotEmpty(benQiHjFinance)) {
            String financeMonth = benQiHjFinance.getFinanceMonth();
            Long saleManId = benQiHjFinance.getSaleManId();
            Long deptId = benQiHjFinance.getDeptId();
            CriteriaQuery<BusOrderDetails> cq = new CriteriaQuery(BusOrderDetails.class);
            cq.eq(true, "saleManId", saleManId);
            cq.eq(true, "orderDetailsState", CommonConstants.ENABLED);
            cq.eq(true, "deptId", deptId);
            cq.and(e->e.likeRight("saleDate",financeMonth).or().likeRight("budan",financeMonth));
            cq.orderByAsc("saleDate");
            //查询订单明细
            List<BusOrderDetails> orderDetailsList = orderDetailsService.list(cq);
            //计算本期数据
            List<BusFinanceDetails> detailsList = initBusFinanceDetails2(orderDetailsList, benQiHjFinance);
            return detailsList;
        }
        return null;
    }


    /**
     * 计算上期对账明细数据
     *
     * @param orderDetailsList
     * @param benQiHjFinance
     * @return
     */
    @Override
    public List<BusFinanceDetails> initLastBusFinanceDetails(List<BusOrderDetails> orderDetailsList, BusFinance benQiHjFinance) {
        Long saleManId = benQiHjFinance.getSaleManId();
        Long deptId = benQiHjFinance.getDeptId();
        List<BusFinanceDetails> detailsList = new ArrayList<>();
        //本期月份最后一天
        String lastDay = DateUtils.format(DateUtils.getLastDayOfMonth(benQiHjFinance.getFinanceMonth() + "-01"));
        if (FlymeUtils.isNotEmpty(orderDetailsList)) {
            BusDept dept = deptService.getById(deptId);
            BusSaleman saleman = salemanService.getById(saleManId);
            String financeMonth = benQiHjFinance.getFinanceMonth();
            EntityMap customBondMap = new EntityMap();

            for (BusOrderDetails orderDetails : orderDetailsList) {
                BigDecimal customBond = FlymeUtils.getBigDecimal(orderDetails.getCustomBond(), "0");
                BigDecimal overAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomOverBond(), "0");
                Long orderDetailsId = orderDetails.getOrderDetailsId();
                BusFinanceDetails busFinanceDetails = new BusFinanceDetails();
                busFinanceDetails.setFinanceId(benQiHjFinance.getFinanceId());
                busFinanceDetails.setOrderDetailsId(orderDetailsId);
                busFinanceDetails.setOrderId(orderDetails.getOrderId());
                Long orderId = orderDetails.getOrderId();
                BusOrder order = orderService.getById(orderDetails.getOrderId());
                BusDrugs drugs = drugsService.getById(orderDetails.getDrugsId());
                BusCustom custom = customService.getById(orderDetails.getCustomId());
                BusDrugslot drugslot = drugslotService.getById(orderDetails.getDrugsLotId());
                if (FlymeUtils.isNotEmpty(drugslot)) {
                    busFinanceDetails.setDrugsLotNo(drugslot.getDrugsLotNo());
                }
                busFinanceDetails.setCustomName(custom.getCustomName());
                busFinanceDetails.setDrugsName(drugs.getDrugsName());
                busFinanceDetails.setDrugsSpec(drugs.getDrugsSpec());
                busFinanceDetails.setSaleNum(orderDetails.getSaleNum().toString());
                busFinanceDetails.setOrderNo(order.getOrderNo());
                if (FlymeUtils.isNotEmpty(orderDetails.getSaleDate())) {
                    busFinanceDetails.setSaleDate(DateUtils.formatDate(orderDetails.getSaleDate()));
                }
                busFinanceDetails.setDeptName(dept.getDeptName());
                busFinanceDetails.setSalePrice(orderDetails.getSalePrice());
                busFinanceDetails.setRemark(orderDetails.getRemark());
                busFinanceDetails.setSaleManName(saleman.getSaleManName());
                busFinanceDetails.setSaleAmount(FlymeUtils.getBigDecimal(orderDetails.getSaleAmount(), "0"));


                String rekuanDate = orderDetails.getRenkuanDate();
                //排除导出时下月回款数据
                if (FlymeUtils.isNotEmpty(rekuanDate) && DateUtils.le(rekuanDate + "-01", lastDay)) {
                    busFinanceDetails.setRenkuanDate(orderDetails.getRenkuanDate());
                    busFinanceDetails.setReturnDate(orderDetails.getReturnDate());
                    BigDecimal returnAmount = FlymeUtils.getBigDecimal(orderDetails.getReturnAmount(), "0");
                    busFinanceDetails.setReturnAmount(returnAmount);
                }

                BigDecimal customBondAmount = customBond.add(overAmount);
                busFinanceDetails.setCustomBondAmount(customBondAmount);
                if (FlymeUtils.isNotEmpty(order.getTakeDate())) {
                    busFinanceDetails.setTakeDate(DateUtils.formatDate(order.getTakeDate()));
                }
                //应结算金额
                BigDecimal settleAmount = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount(), "0");
                BigDecimal settleAmount2 = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount2(), "0");
                //应结算总金额
                BigDecimal settleTotalAmount = settleAmount.add(settleAmount2);
                //已结算金额
                BigDecimal settleRealAmount = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount(), "0");
                BigDecimal settleRealAmount2 = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount2(), "0");
                BigDecimal noSettleAmount = new BigDecimal("0");

                //结算日期
                String settlePayDate = orderDetails.getSettlePayDate();
                String settlePayDate1 = orderDetails.getSettlePayDate2();

                busFinanceDetails.setSettleAmount(settleTotalAmount);
                BigDecimal yesSettleAmount = new BigDecimal("0");

                if (FlymeUtils.isNotEmpty(settlePayDate) && DateUtils.le(settlePayDate, lastDay)) {
                    yesSettleAmount = yesSettleAmount.add(settleRealAmount);
                    busFinanceDetails.setSettlePayDate(settlePayDate);
                }

                if (FlymeUtils.isNotEmpty(settlePayDate1) && DateUtils.le(settlePayDate1, lastDay)) {
                    yesSettleAmount = yesSettleAmount.add(settleRealAmount2);
                    busFinanceDetails.setSettlePayDate(settlePayDate1);
                }
                noSettleAmount = settleTotalAmount.subtract(yesSettleAmount);
                busFinanceDetails.setYesSettleAmount(yesSettleAmount);
                busFinanceDetails.setNoSettleAmount(noSettleAmount);

                BigDecimal returnCustomBond = FlymeUtils.getBigDecimal(orderDetails.getReturnCustomBond(), "0");
                String customBondRetDate = orderDetails.getCustomBondRetDate();

                if (FlymeUtils.isNotEmpty(customBondRetDate) && DateUtils.le(customBondRetDate, lastDay)) {
                    busFinanceDetails.setReturnCustomBond(returnCustomBond);
                    busFinanceDetails.setReturnCustomBondDate(customBondRetDate);
                }

                detailsList.add(busFinanceDetails);

            }
        }
        return detailsList;
    }


    /**
     * 计算明细数据
     *
     * @param orderDetailsList
     * @param busFinance
     * @return
     */
    private List<BusFinanceDetails> initBusFinanceDetails2(List<BusOrderDetails> orderDetailsList, BusFinance benQiHjFinance) {
        Long saleManId = benQiHjFinance.getSaleManId();
        Long deptId = benQiHjFinance.getDeptId();
        List<BusFinanceDetails> detailsList = new ArrayList<>();
        //本期月份第一天
        String lastFirstDay = benQiHjFinance.getFinanceMonth() + "-01";
        //本期月份最后一天
        String lastDay = DateUtils.format(DateUtils.getLastDayOfMonth(lastFirstDay));
        if (FlymeUtils.isNotEmpty(orderDetailsList)) {
            BusDept dept = deptService.getById(deptId);
            BusSaleman saleman = salemanService.getById(saleManId);
            //发货金额
            BigDecimal totalSaleAmount = new BigDecimal("0");
            //回款金额
            BigDecimal totalReturnAmount = new BigDecimal("0");
            BigDecimal debtAmount = new BigDecimal("0");
            BigDecimal totalCustomBond = new BigDecimal("0");
            BigDecimal totalYesSettleAmount = new BigDecimal("0");
            BigDecimal totalSettleAmount = new BigDecimal("0");
            BigDecimal totalNoSettleAmount = new BigDecimal("0");
            BigDecimal totalReturnCustomBond = new BigDecimal("0");
            String financeMonth = benQiHjFinance.getFinanceMonth();
            EntityMap customBondMap = new EntityMap();
            for (BusOrderDetails orderDetails : orderDetailsList) {
                String budan=FlymeUtils.getString(orderDetails.getBudan(),"0");
                BigDecimal customBond = FlymeUtils.getBigDecimal(orderDetails.getCustomBond(), "0");
                BigDecimal overAmount = FlymeUtils.getBigDecimal(orderDetails.getCustomOverBond(), "0");
                Long orderDetailsId = orderDetails.getOrderDetailsId();
                BusFinanceDetails busFinanceDetails = new BusFinanceDetails();
                busFinanceDetails.setFinanceDetailsId(orderDetailsId);
                busFinanceDetails.setFinanceId(benQiHjFinance.getFinanceId());
                busFinanceDetails.setOrderDetailsId(orderDetailsId);
                busFinanceDetails.setOrderId(orderDetails.getOrderId());
                Long orderId = orderDetails.getOrderId();
                BusOrder order = orderService.getById(orderDetails.getOrderId());
                BusDrugs drugs = drugsService.getById(orderDetails.getDrugsId());
                BusCustom custom = customService.getById(orderDetails.getCustomId());
                BusDrugslot drugslot = drugslotService.getById(orderDetails.getDrugsLotId());
                if (FlymeUtils.isNotEmpty(drugslot)) {
                    busFinanceDetails.setDrugsLotNo(drugslot.getDrugsLotNo());
                }
                busFinanceDetails.setCustomName(custom.getCustomName());
                busFinanceDetails.setCustomBondType(order.getCustomBondType());
                busFinanceDetails.setDrugsName(drugs.getDrugsName());
                busFinanceDetails.setRemark(orderDetails.getRemark());
                busFinanceDetails.setDrugsSpec(drugs.getDrugsSpec());
                busFinanceDetails.setSaleNum(orderDetails.getSaleNum().toString());
                busFinanceDetails.setOrderNo(order.getOrderNo());
                if (FlymeUtils.isNotEmpty(orderDetails.getSaleDate())) {
                    busFinanceDetails.setSaleDate(DateUtils.formatDate(orderDetails.getSaleDate()));
                }
                busFinanceDetails.setDeptName(dept.getDeptName());
                busFinanceDetails.setSalePrice(orderDetails.getSalePrice());
                busFinanceDetails.setSaleManName(saleman.getSaleManName());
                BigDecimal saleAmount = FlymeUtils.getBigDecimal(orderDetails.getSaleAmount(), "0");
                busFinanceDetails.setSaleAmount(saleAmount);


                String returnDate = orderDetails.getReturnDate();
                String renkuanDate = orderDetails.getRenkuanDate();
                busFinanceDetails.setRenkuanDate(orderDetails.getRenkuanDate());
                BigDecimal returnAmount = FlymeUtils.getBigDecimal(orderDetails.getReturnAmount(), "0");
                busFinanceDetails.setReturnAmount(returnAmount);
                if (FlymeUtils.isNotEmpty(renkuanDate)) {
                    busFinanceDetails.setReturnDate(returnDate);
                    if (renkuanDate.equals(benQiHjFinance.getFinanceMonth())) {
                        //只统计本期
                        totalReturnAmount = totalReturnAmount.add(returnAmount);
                    }
                }
                BigDecimal customBondAmount = customBond.add(overAmount);
                busFinanceDetails.setCustomBondAmount(customBondAmount);
                //保证金合计
                totalCustomBond = totalCustomBond.add(customBondAmount);

                //销售金额合计
                totalSaleAmount = totalSaleAmount.add(saleAmount);
                if (FlymeUtils.isNotEmpty(order.getTakeDate())) {
                    busFinanceDetails.setTakeDate(DateUtils.formatDate(order.getTakeDate()));
                }
                //结算日期
                String settlePayDate = orderDetails.getSettlePayDate();
                String settlePayDate1 = orderDetails.getSettlePayDate2();


                //应结算金额
                BigDecimal settleAmount = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount(), "0");
                BigDecimal settleAmount2 = FlymeUtils.getBigDecimal(orderDetails.getSettleAmount2(), "0");
                //应结算总金额
                BigDecimal settleTotalAmount = settleAmount.add(settleAmount2);
                busFinanceDetails.setSettleAmount(settleTotalAmount);

                //已结算金额
                BigDecimal settleRealAmount = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount(), "0");
                BigDecimal settleRealAmount2 = FlymeUtils.getBigDecimal(orderDetails.getSettleRealAmount2(), "0");


                BigDecimal yesSettleAmount = settleRealAmount.add(settleRealAmount2);


                if (FlymeUtils.isNotEmpty(settlePayDate)) {
                    if ((DateUtils.ge(settlePayDate, lastFirstDay) && DateUtils.ge(lastDay, settlePayDate))||budan.equals(benQiHjFinance.getFinanceMonth())) {
                        totalYesSettleAmount = totalYesSettleAmount.add(settleRealAmount);
                    }
                }
                if (FlymeUtils.isNotEmpty(settlePayDate1)) {
                    if ((DateUtils.ge(settlePayDate1, lastFirstDay) && DateUtils.ge(lastDay, settlePayDate1))||budan.equals(benQiHjFinance.getFinanceMonth())) {
                        totalYesSettleAmount = totalYesSettleAmount.add(settleRealAmount2);
                    }
                }

                BigDecimal noSettleAmount = settleTotalAmount.subtract(yesSettleAmount);
                busFinanceDetails.setSettlePayDate(settlePayDate);
                busFinanceDetails.setYesSettleAmount(yesSettleAmount);
                busFinanceDetails.setNoSettleAmount(noSettleAmount);
                totalSettleAmount = totalSettleAmount.add(settleTotalAmount);

                totalNoSettleAmount = totalNoSettleAmount.add(noSettleAmount);

                BigDecimal returnCustomBond = FlymeUtils.getBigDecimal(orderDetails.getReturnCustomBond(), "0");
                String customBondRetDate = orderDetails.getCustomBondRetDate();
                busFinanceDetails.setReturnCustomBond(returnCustomBond);
                busFinanceDetails.setReturnCustomBondDate(customBondRetDate);

                if (FlymeUtils.isNotEmpty(customBondRetDate)) {
                    //只统计本期退款金额
                    if ((DateUtils.ge(customBondRetDate, lastFirstDay) && DateUtils.ge(lastDay, customBondRetDate))||budan.equals(benQiHjFinance.getFinanceMonth())) {
                        totalReturnCustomBond = totalReturnCustomBond.add(returnCustomBond);
                    }
                }
                debtAmount = totalSaleAmount.subtract(totalReturnAmount);
                detailsList.add(busFinanceDetails);
            }

            benQiHjFinance.setNoSettleAmount(totalNoSettleAmount);
            benQiHjFinance.setSaleAmount(totalSaleAmount);
            benQiHjFinance.setCustomBondAmount(totalCustomBond);
            benQiHjFinance.setCustomBondReturnAmount(totalReturnCustomBond);
            benQiHjFinance.setReturnAmount(totalReturnAmount);
            benQiHjFinance.setDebtAmount(debtAmount);
            benQiHjFinance.setImportData(CommonConstants.DISABLED);
            benQiHjFinance.setSettleRealAmount(totalYesSettleAmount);
            benQiHjFinance.setSettleAbleAmount(totalSettleAmount);
        } else {
            benQiHjFinance.setNoSettleAmount(new BigDecimal("0"));
            benQiHjFinance.setSaleAmount(new BigDecimal("0"));
            benQiHjFinance.setCustomBondAmount(new BigDecimal("0"));
            benQiHjFinance.setCustomBondReturnAmount(new BigDecimal("0"));
            benQiHjFinance.setReturnAmount(new BigDecimal("0"));
            benQiHjFinance.setDebtAmount(new BigDecimal("0"));
            benQiHjFinance.setImportData(CommonConstants.DISABLED);
            benQiHjFinance.setSettleRealAmount(new BigDecimal("0"));
            benQiHjFinance.setSettleAbleAmount(new BigDecimal(0));
        }
        return detailsList;
    }

    public List<BusFinanceDetails> listByFinanceId(Long financeId) {
        CriteriaQuery cq = new CriteriaQuery(BusFinanceDetails.class);
        cq.eq(true, "financeId", financeId);
        return list(cq);
    }
}
